//记录整个过程
import Snake from "./snake";
import Foot from "./foot";
import ScorePanel from "./ScorePanel";

export default class GameCtrol {
  // 定义三个属性
  snake: Snake;
  foot: Foot;
  scorePanel: ScorePanel;
  //存储蛇的移动方向，也就是按键的方向
  direction: string;
  //记录蛇是否结束
  isLive: boolean = true;
  constructor() {
    this.snake = new Snake();
    this.foot = new Foot();
    this.scorePanel = new ScorePanel();
    this.init();
  }
  //开始游戏
  init() {
    //给页面绑定键盘事件  注意这里this指向document
    //这里如果想要this改编为GameCtrol那么有两种方式
    //第一种使用this.keydownHandler.bind(this) 或者keydownHandler直接使用箭头函数即可
    document.addEventListener("keydown", this.keydownHandler.bind(this));
    this.run();
  }

  //键盘按下的相响应函数
  keydownHandler = (event: KeyboardEvent) => {
    this.direction = event.key;
  };

  //常见一个控制蛇移动的方法
  run() {
    /**
     * 根据方向(this.direction)来时蛇的位置改变
     * 向上top减少
     * 向下to增加
     * 向left减少
     * 向right增加
     * **/
    //获取蛇的坐标

    let X = this.snake.X;
    let Y = this.snake.Y;

    switch (this.direction) {
      case "ArrowUp":
        Y -= 10;
        break;
      case "ArrowDown":
        Y += 10;
        break;
      case "ArrowLeft":
        X -= 10;
        break;
      case "ArrowRight":
        X += 10;
        break;
    }
    //判断蛇是否吃到食物
    this.checkEat(X, Y);
    try {
      this.snake.X = X;
      this.snake.Y = Y;
    } catch (e) {
      //出现异常游戏结束
      alert(e.message);
      this.isLive = false;
    }
    /**让蛇一直走需要执行setTimout，为什么不在监听中进行调用，原因很简单就是 每次按下才会走，不按下就停止了**/
    this.isLive &&
      setTimeout(this.run.bind(this), 300 * this.scorePanel.level - 1);
  }

  //定义一个方法，用来检查是否蛇吃到了食物
  checkEat(X: number, Y: number) {
    if (X === this.foot.X && Y === this.foot.Y) {
      //食物的位置发生改变
      this.foot.change();
      //分数增加
      this.scorePanel.addScore();
      //蛇增加一节
      this.snake.addBody();
    }
  }
}
